package com.lty.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lty.mapper.QuartzJobMapper;
import com.lty.model.entity.QuartzJob;
import com.lty.service.QuartzJobService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.CronExpression;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

@Slf4j
@Service
@RequiredArgsConstructor
@Transactional
public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob> implements QuartzJobService {
    private final Scheduler scheduler;

    @Override
    public void addJob(QuartzJob job) throws SchedulerException {
        // 1. 验证Cron表达式
        if (!CronExpression.isValidExpression(job.getCron())) {
            throw new IllegalArgumentException("无效的Cron表达式: " + job.getCron());
        }

        // 2. 创建JobDetail
        JobDetail jobDetail = JobBuilder.newJob(getJobClass(job.getJobClass()))
                .withIdentity(job.getId(), "JOB_GROUP")
                .withDescription(job.getDescription())
                .build();

        // 3. 设置参数
        if (job.getParams() != null) {
            jobDetail.getJobDataMap().put("params", job.getParams());
        }

        // 4. 创建CronTrigger
        CronTrigger trigger = TriggerBuilder.newTrigger()
                .withIdentity(job.getId() + "_TRIGGER", "TRIGGER_GROUP")
                .withSchedule(CronScheduleBuilder.cronSchedule(job.getCron())
                        .withMisfireHandlingInstructionDoNothing()) // 错过触发的处理策略
                .build();

        // 5. 注册任务
        scheduler.scheduleJob(jobDetail, trigger);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateJob(QuartzJob job) throws SchedulerException {
        updateById(job); // 更新数据库记录
    }

    @Override
    public void deleteJob(String jobId) throws SchedulerException {
        // 1. 暂停该任务的触发器（Trigger）
        scheduler.pauseTrigger(TriggerKey.triggerKey(jobId));
        // 2. 解除该触发器与任务的绑定关系（从调度器中移除 Trigger）
        scheduler.unscheduleJob(TriggerKey.triggerKey(jobId));
        // 3. 最终删除 Job 本身
        scheduler.deleteJob(new JobKey(jobId, "JOB_GROUP"));
        // 删除数据库记录
        removeById(jobId);
    }

    @Override
    public void pauseJob(String jobId) throws SchedulerException {
        // 1. 暂停任务
        scheduler.pauseJob(new JobKey(jobId, "JOB_GROUP"));
        // 2. 更新数据库状态
        QuartzJob job = getById(jobId);
        if (Objects.nonNull(job)) {
            job.setStatus(1); // 1-暂停
            updateById(job);
        }
    }

    @Override
    public void resumeJob(String jobId) throws SchedulerException {
        // 1. 恢复任务
        scheduler.resumeJob(new JobKey(jobId, "JOB_GROUP"));
        // 2. 更新数据库状态
        QuartzJob job = getById(jobId);
        if (Objects.nonNull(job)) {
            job.setStatus(0); // 0-正常
            updateById(job);
        }
    }

    @Override
    public void runJobNow(String jobId) throws SchedulerException {
        JobKey jobKey = new JobKey(jobId);
        scheduler.triggerJob(jobKey);
        log.info("立即执行任务: {}", jobId);
    }

    // 获取Job类
    private Class<? extends Job> getJobClass(String className) {
        try {
            return (Class<? extends Job>) Class.forName(className);
        } catch (ClassNotFoundException e) {
            throw new IllegalArgumentException("找不到Job类: " + className, e);
        }
    }
}
